package cn.mw.cmdb.service.impl;

import cn.mw.cmdb.entity.InstanceInfo;
import cn.mw.cmdb.entity.MwInstanceDetailTabInfo;
import cn.mw.cmdb.enums.InstanceDetailTabEnum;
import cn.mw.cmdb.mongoMapper.InstanceDetailTabMapper;
import cn.mw.cmdb.param.DetailTabSearchParam;
import cn.mw.cmdb.param.InstanceDetailTabParam;
import cn.mw.cmdb.param.MwInstanceBaseInfo;
import cn.mw.cmdb.param.MwKeyValueParam;
import cn.mw.cmdb.util.CMDBTool;
import cn.mw.components.mongodb.entity.CriteriaOpsType;
import cn.mw.components.mongodb.entity.SubCondition;
import cn.mw.components.mongodb.tool.CriteriaWrapper;
import cn.mw.microMonitorCommon.util.ModuleIDManager;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.google.common.base.Strings;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import static cn.mw.cmdb.enums.InstanceDetailTabEnum.monitorDetail;
import static cn.mw.cmdb.param.FunctionModuleEnum.enableMonitor;
import static cn.mw.cmdb.processor.MonitorValue.FunctionModule;

public class InstanceDetailTabServiceImpl extends ModelBaseServiceImpl<MwInstanceDetailTabInfo, Object> {

    private CmdbServiceManage cmdbServiceManage;
    private InstanceDetailTabMapper instanceDetailTabMapper;
    public ModuleIDManager moduleIDManager;

    public static final String ID = "instanceDetailTab";

    public InstanceDetailTabServiceImpl(InstanceDetailTabMapper instanceDetailTabMapper, CmdbServiceManage cmdbServiceManage,
                                        ModuleIDManager moduleIDManager) {
        this.instanceDetailTabMapper = instanceDetailTabMapper;
        this.cmdbServiceManage = cmdbServiceManage;
        this.moduleIDManager = moduleIDManager;
    }

    @Override
    public MwInstanceDetailTabInfo genObject() {
        return new MwInstanceDetailTabInfo();
    }

    @Override
    Object doAdd(MwInstanceDetailTabInfo param) throws Exception {
        MwInstanceBaseInfo mwInstanceBaseInfo = QueryInstanceBaseInfo(param.getInstanceId());
        String instanceGroupId = mwInstanceBaseInfo.getGroupId();
        if (!Strings.isNullOrEmpty(instanceGroupId)) {
            DetailTabSearchParam detailTabSearchParam = new DetailTabSearchParam();
            detailTabSearchParam.setGroupId(instanceGroupId);
            List<MwInstanceDetailTabInfo> mwInstanceDetailTabInfos = doSelectByGroupId(detailTabSearchParam);
            param.setModelGroupId(instanceGroupId);
            //如果数据库中有数据,则更新
            if (CollectionUtils.isNotEmpty(mwInstanceDetailTabInfos)) {
                doUpdate(param);
            } else {
                //新增数据
                instanceDetailTabMapper.insert(param);
            }
            return true;
        }
        return false;
    }

    @Override
    boolean doUpdate(MwInstanceDetailTabInfo param) throws Exception {
        String groupId = "";
        if (Strings.isNullOrEmpty(param.getModelGroupId())) {
            MwInstanceBaseInfo mwInstanceBaseInfo = QueryInstanceBaseInfo(param.getId());
            groupId = mwInstanceBaseInfo.getGroupId();
        } else {
            groupId = param.getModelGroupId();
        }
        Query query = new Query(CriteriaWrapper.where(MwInstanceDetailTabInfo::getModelGroupId).is(groupId));
        //根据类注解信息产生更新信息
        Update update = CMDBTool.genMongoUpdate(param, null, null);
        CMDBTool.updateFirst(instanceDetailTabMapper, query, update);
        return true;
    }

    @Override
    boolean doRemove(MwInstanceDetailTabInfo param) throws Exception {
        return false;
    }

    @Override
    Object doBatchAdd(Object params) throws Exception {
        return false;
    }

    @Override
    boolean doBatchUpdate(Object params) {
        return false;
    }

    @Override
    MwInstanceDetailTabInfo doSelectById(Object id) throws Exception {
        return null;
    }

    public MwInstanceDetailTabInfo queryDetailTabInfo(InstanceDetailTabParam detailTabParam) throws Exception {
        MwInstanceBaseInfo mwInstanceBaseInfo = QueryInstanceBaseInfo(detailTabParam.getInstanceId());
        String groupId = mwInstanceBaseInfo.getGroupId();
        DetailTabSearchParam detailTabSearchParam = new DetailTabSearchParam();
        detailTabSearchParam.setGroupId(groupId);
        List<MwInstanceDetailTabInfo> mwInstanceDetailTabInfos = doSelectByGroupId(detailTabSearchParam);
        MwInstanceDetailTabInfo detailTabInfos = new MwInstanceDetailTabInfo();
        if (CollectionUtils.isNotEmpty(mwInstanceDetailTabInfos)) {
            detailTabInfos = mwInstanceDetailTabInfos.get(0);
        } else {
            detailTabInfos.setTabList(mwInstanceBaseInfo.getFunctionModeList());
        }
        if (Strings.isNullOrEmpty(detailTabParam.getHostId())) {
            List<MwKeyValueParam> tabList = detailTabInfos.getTabList();
            Iterator<MwKeyValueParam> it = tabList.iterator();
            while (it.hasNext()) {
                MwKeyValueParam next = it.next();
                if (next != null && monitorDetail.getType().equals(next.getValue())) {
                    it.remove();
                }
            }
        }
        return detailTabInfos;
    }

    /**
     * 根据模型分组id查询监控详情tab信息
     *
     * @param detailTabSearchParam
     * @return
     */
    private List<MwInstanceDetailTabInfo> doSelectByGroupId(DetailTabSearchParam detailTabSearchParam) {
        if (!Strings.isNullOrEmpty(detailTabSearchParam.getGroupId())) {
            detailTabSearchParam.addSubCondition(CMDBTool.getFieldName(MwInstanceDetailTabInfo::getModelGroupId)
                    , new SubCondition(CriteriaOpsType.is.name(), detailTabSearchParam.getGroupId()));
        }
        Criteria criteria = genCriteria(detailTabSearchParam);
        List<MwInstanceDetailTabInfo> mwInstanceDetailTabInfos = CMDBTool.selectListByAggregate(MwInstanceDetailTabInfo.class, instanceDetailTabMapper, criteria);
        return mwInstanceDetailTabInfos;
    }

    /**
     * 资产详情tab信息下拉选择数据
     *
     * @param detailTabParam
     * @return
     * @throws Exception
     */
    public List<MwKeyValueParam> detailSelectDropInfo(InstanceDetailTabParam detailTabParam) throws Exception {
        MwInstanceBaseInfo mwInstanceBaseInfo = QueryInstanceBaseInfo(detailTabParam.getInstanceId());
        List<MwKeyValueParam> list = new ArrayList<>();
        list.addAll(mwInstanceBaseInfo.getFunctionModeList());
        return list;
    }


    @Override
    List<MwInstanceDetailTabInfo> doSelectList(Object param) throws Exception {
        return null;
    }

    @Override
    boolean doBatchRemove(Object params) throws Exception {
        return false;
    }

    private MwInstanceBaseInfo QueryInstanceBaseInfo(String instanceId) {
        MwInstanceBaseInfo mwInstanceBaseInfo = new MwInstanceBaseInfo();
        InstanceServiceImpl modelService = (InstanceServiceImpl) cmdbServiceManage.getModelService(InstanceServiceImpl.ID);
        InstanceInfo param = new InstanceInfo();
        param.setId(instanceId);
        InstanceInfo instanceInfo = modelService.doSelectById(param);
        String groupId = "";
        List<MwKeyValueParam> functionModeList = new ArrayList<>();
        //获取所有非功能模块的tab信息
        functionModeList.addAll(InstanceDetailTabEnum.getDefaultManageTab());
        if (instanceInfo != null) {
            if (CollectionUtils.isNotEmpty(instanceInfo.getPath())) {
                groupId = instanceInfo.getPath().get(instanceInfo.getPath().size()-1);
                mwInstanceBaseInfo.setGroupId(groupId);
            }
            //资产功能权限
            if (instanceInfo.getData() != null && instanceInfo.getData().get(FunctionModule) != null) {
                List<String> functionModule = (List<String>) instanceInfo.getData().get(FunctionModule);
                for (String str : functionModule) {
                    MwKeyValueParam tabType = InstanceDetailTabEnum.getDetailTabType(str);
                    if (tabType != null) {
                        functionModeList.add(tabType);
                    }
                }
            }
            MwKeyValueParam tabType = InstanceDetailTabEnum.getDetailTabByModelId(instanceInfo.getModelId());
            if (tabType != null) {
                functionModeList.add(tabType);
                //如果有特殊的监控页面视图(虚拟化视图，Citrix视图等)，监控详情tab去除，不显示
                MwKeyValueParam monitorDetailKey = InstanceDetailTabEnum.getDetailTabType(monitorDetail.getCode());
                functionModeList.remove(monitorDetailKey);
            }
        }
        mwInstanceBaseInfo.setFunctionModeList(functionModeList);
        return mwInstanceBaseInfo;
    }
}